import { PickerItemData } from '../Picker/config';

export function buildJson(data: PickerItemData[], canvas: HTMLElement) {
    const children = [...canvas.children];

    return children
        .map((el: HTMLElement) => {
            const current = data.find(item => item.key === el.dataset.key);

            if (!current) {
                return;
            }

            if (current.type === 'layout') {
                current.children = buildJson(data, el);
            }

            return current;
        })
        .filter(Boolean);
}

function transformConponentProps(props: object) {
    return typeof props === 'object'
        ? Object.entries(props)
              .reduce((str, [k, v]) => {
                  str += ` ${k}=${Number(v) ? `{${v}}` : `"${v}"`} `;

                  return str;
              }, ``)
              .trim()
        : '';
}

function buildJsx(data: PickerItemData[], wrapper?: (templ: string, data: PickerItemData) => string) {
    return data.reduce((str, item) => {
        let chunk: string;

        if (item.type === 'layout' && item.children?.length) {
            chunk = `
        <${item.componentName} ${transformConponentProps(item.componentProps)}>
            ${buildJsx(
                item.children,
                (templ, _data) => `
                <Col ${_data.span ? `span={${_data.span}}` : ''}>
                    ${templ}
                </Col>
                `
            )}
        </${item.componentName}>
                `;
        } else {
            chunk = `
            <FormItem ${transformConponentProps(item.formProps)}>
                <${item.componentName} ${transformConponentProps(item.componentProps)} />
            </FormItem>
                `;
        }

        if (wrapper) {
            chunk = wrapper(chunk, item);
        }

        str += chunk;

        return str;
    }, ``);
}

function getImports(data: PickerItemData[]) {
    return [...new Set(data.map(item => item.componentName))].join(', ');
}

export function buildCode(data: PickerItemData[], canvas: HTMLElement) {
    const json = buildJson(data, canvas);

    return `
import React from 'react';
import { message, Col, ${getImports(data)} } from 'antd';
import { withForm, FormItem, useForm } from 'react-antd-formutil';

function MyForm() {
    const { $invalid, $batchDirty, $getFirstError } = useForm();
    const submit = () => {
        if ($invalid) {
            $batchDirty(true);
            message.error($getFirstError());

            return;
        }

        // ...
    }

    return (
        <div>
            ${buildJsx(json)}
        </div>
    )
}

export default withForm(MyForm)
    `;
}
